library(stringr)
library(tidyverse)
library(bigrquery)
library(MuMIn)
response <- try(system('~/google-cloud-sdk/bin/gcloud projects list --quiet', intern = T))
projectid <- strsplit(response[2], " ")[[1]][1]
options(na.action = "na.fail")
source("./dredge_functions.R")
dredge_and_subset <- function(data) {
model <- lm(
response ~ foraging_niche + trophic_niche + is_nocturnal + pc1 + pc2 + pc3 + pc4 + total_species,
data=data
)
dredge_result <- dredge(model)
summary(model.avg(dredge_result, subset = delta < 10))
}
load_niche_data <- function() {
filename <- 'species_analysis_cache.csv'
if (!file.exists(filename)) {
sql <- "
SELECT
niche_name,
foraging_niche,
trophic_niche,
is_noctural,
total_species,
merlin_10_perc_ratio,
merlin_20_perc_ratio,
birdlife_10_perc_ratio,
birdlife_20_perc_ratio,
either_10_perc_ratio,
either_20_perc_ratio,
both_10_perc_ratio,
both_20_perc_ratio,
body_morphspace.pc1.mean AS pc1,
body_morphspace.pc2.mean AS pc2,
body_morphspace.pc3.mean AS pc3,
body_morphspace.pc4.mean AS pc4
FROM `endless-matter-297214.model2.niche_analysis_model` LIMIT 1000
"
tb <- bq_project_query(projectid, sql)
data <- bq_table_download(tb)
write_csv(data, filename)
}
data <- read_csv(filename)
data[is.na(data$foraging_niche),]$foraging_niche <- 'Omnivore'
data$foraging_niche = as.factor(data$foraging_niche)
data$trophic_niche = as.factor(data$trophic_niche)
data$is_nocturnal = as.factor(data$is_noctural)
data
}
data_for_response <- function(column_name_for_response) {
data <- load_niche_data()
names(data)[names(data) == column_name_for_response] <- "response"
data[,c("niche_name", "response", "foraging_niche", "trophic_niche", "is_nocturnal", "pc1", "pc2", "pc3", "pc4", "total_species")]
}
| 0.25 Percentile - 10% of species |
merlin_10_data <- data_for_response('merlin_10_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
merlin_10_data
merlin_10_result <- dredge_and_subset(merlin_10_data)
Fixed term is "(Intercept)"
merlin_10_summ <- model_summary('merlin_10', 'species', merlin_10_result)
merlin_10_summ
birdlife_10_data <- data_for_response('birdlife_10_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
birdlife_10_result <- dredge_and_subset(birdlife_10_data)
Fixed term is "(Intercept)"
birdlife_10_summ <- model_summary('birdlife_10', 'species', birdlife_10_result)
birdlife_10_summ
both_10_data <- data_for_response('both_10_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
both_10_result <- dredge_and_subset(both_10_data)
Fixed term is "(Intercept)"
both_10_summ <- model_summary('both_10', 'species', both_10_result)
both_10_summ
either_10_data <- data_for_response('either_10_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
either_10_result <- dredge_and_subset(either_10_data)
Fixed term is "(Intercept)"
either_10_summ <- model_summary('either_10', 'species', either_10_result)
either_10_summ
| Full result for 10% of species |
all_species_results <- full_join(full_join(merlin_10_summ, birdlife_10_summ), full_join(both_10_summ, either_10_summ))
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
write_csv(all_species_results, "species_analysis_result_10_perc.csv")
| 0.75 Percentile - 20% of species |
merlin_20_data <- data_for_response('merlin_20_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
merlin_20_result <- dredge_and_subset(merlin_20_data)
Fixed term is "(Intercept)"
merlin_20_summ <- model_summary('merlin_20', 'species', merlin_20_result)
merlin_20_summ
birdlife_20_data <- data_for_response('birdlife_20_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
birdlife_20_result <- dredge_and_subset(birdlife_20_data)
Fixed term is "(Intercept)"
birdlife_20_summ <- model_summary('birdlife_20', 'species', birdlife_20_result)
birdlife_20_summ
both_20_data <- data_for_response('both_20_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
both_20_result <- dredge_and_subset(both_20_data)
Fixed term is "(Intercept)"
both_20_summ <- model_summary('both_20', 'species', both_20_result)
both_20_summ
either_20_data <- data_for_response('either_20_perc_ratio')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
niche_name = col_character(),
foraging_niche = col_character(),
trophic_niche = col_character(),
is_noctural = col_logical(),
total_species = col_double(),
merlin_10_perc_ratio = col_double(),
merlin_20_perc_ratio = col_double(),
birdlife_10_perc_ratio = col_double(),
birdlife_20_perc_ratio = col_double(),
either_10_perc_ratio = col_double(),
either_20_perc_ratio = col_double(),
both_10_perc_ratio = col_double(),
both_20_perc_ratio = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double()
)
either_20_result <- dredge_and_subset(either_20_data)
Fixed term is "(Intercept)"
either_20_summ <- model_summary('either_20', 'species', either_20_result)
either_20_summ
| Full result for 10% of species |
all_species_results <- full_join(full_join(merlin_20_summ, birdlife_20_summ), full_join(both_20_summ, either_20_summ))
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
write_csv(all_species_results, "species_analysis_result_20_perc.csv")
| Comparing the 2 percentiles |
ggplot(merlin_10_data, aes(x = response)) + geom_bar(width = 0.1)
Warning: position_stack requires non-overlapping x intervals

bind_sets <- function(first_percentile, second_percentile) {
first_percentile$percentile <- "0.25"
second_percentile$percentile <- "0.75"
rbind(first_percentile, second_percentile)
}
merlin_species_data <- bind_sets(merlin_10_data, merlin_20_data)
birdlife_species_data <- bind_sets(birdlife_10_data, birdlife_20_data)
either_species_data <- bind_sets(either_10_data, either_20_data)
both_species_data <- bind_sets(both_10_data, both_20_data)
ggplot(merlin_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

merlin_trophic_niche_niche_anova <- aov(response~trophic_niche + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_trophic_niche_niche_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 1.762 0.1958 1.679 0.0943 .
Residuals 258 30.084 0.1166
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 59.65 2.29e-13 ***
Residuals 267 6.749 0.0253
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_trophic_niche_niche_anova_i <- aov(response~trophic_niche * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_trophic_niche_niche_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 1.762 0.1958 1.679 0.0943 .
Residuals 258 30.084 0.1166
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 69.821 4.05e-15 ***
trophic_niche:percentile 9 1.177 0.1308 6.057 1.03e-07 ***
Residuals 258 5.571 0.0216
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
pairwise.wilcox.test(merlin_diff_data$increase, merlin_diff_data$trophic_niche)
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
cannot compute exact p-value with ties
Pairwise comparisons using Wilcoxon rank sum test with continuity correction
data: merlin_diff_data$increase and merlin_diff_data$trophic_niche
Aquatic predator Frugivore Granivore Herbivore aquatic Herbivore terrestrial Invertivore Nectarivore Omnivore Scavenger
Frugivore 0.5331 - - - - - - - -
Granivore 1.0000 1.0000 - - - - - - -
Herbivore aquatic 1.0000 0.1167 1.0000 - - - - - -
Herbivore terrestrial 1.0000 1.0000 1.0000 1.0000 - - - - -
Invertivore 0.0076 1.0000 1.0000 0.0051 1.0000 - - - -
Nectarivore 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 - - -
Omnivore 0.2684 1.0000 1.0000 0.0679 1.0000 1.0000 1.0000 - -
Scavenger 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 -
Vertivore 1.0000 1.0000 1.0000 0.5929 1.0000 1.0000 1.0000 1.0000 1.0000
P value adjustment method: holm
library(multcomp)
merlin_increase_tropic_niche_anova <-aov(increase~trophic_niche, data=merlin_diff_data)
summary(merlin_increase_tropic_niche_anova)
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 3.941 0.4379 3.689 0.000229 ***
Residuals 258 30.629 0.1187
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_tropic_niche_tukey <- cld(glht(merlin_increase_tropic_niche_anova, linfct=mcp(trophic_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
merlin_increase_tropic_niche_tukey
Aquatic predator Frugivore Granivore Herbivore aquatic Herbivore terrestrial Invertivore Nectarivore Omnivore
"bc" "ab" "ac" "c" "ac" "a" "ac" "ab"
Scavenger Vertivore
"ac" "ac"
plot(merlin_increase_tropic_niche_tukey)

with.tukey.label.as.group <- function(tukey, dataset, join_by) {
labels <- data.frame(tukey$mcletters$Letters)
labels$category <- rownames(labels)
colnames(labels) <- c("group", "category")
left_join(dataset, labels, by = join_by)
}

ggplot(birdlife_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_trophic_niche_niche_anova <- aov(response~trophic_niche + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_trophic_niche_niche_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 1.696 0.1885 1.605 0.114
Residuals 258 30.292 0.1174
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 60.18 1.84e-13 ***
Residuals 267 5.890 0.0221
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_trophic_niche_niche_anova_i <- aov(response~trophic_niche * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_trophic_niche_niche_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 1.696 0.1885 1.605 0.114
Residuals 258 30.292 0.1174
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 64.018 4.19e-14 ***
trophic_niche:percentile 9 0.540 0.0600 2.893 0.00282 **
Residuals 258 5.350 0.0207
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_tropic_niche_anova <-aov(increase~trophic_niche, data=birdlife_diff_data)
summary(birdlife_increase_tropic_niche_anova)
Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche 9 2.21 0.2453 1.791 0.0703 .
Residuals 258 35.35 0.1370
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_tropic_niche_tukey <- cld(glht(birdlife_increase_tropic_niche_anova, linfct=mcp(trophic_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
birdlife_increase_tropic_niche_tukey
Aquatic predator Frugivore Granivore Herbivore aquatic Herbivore terrestrial Invertivore Nectarivore Omnivore
"b" "ab" "ab" "ab" "ab" "a" "ab" "ab"
Scavenger Vertivore
"ab" "ab"

ggplot(either_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

ggplot(both_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

nrow(merlin_10_data[merlin_10_data$response > 0,])
[1] 96
nrow(merlin_20_data[merlin_20_data$response > 0,])
[1] 128
nrow(birdlife_10_data[birdlife_10_data$response > 0,])
[1] 87
nrow(birdlife_20_data[birdlife_20_data$response > 0,])
[1] 124
nrow(either_10_data[either_10_data$response > 0,])
[1] 94
nrow(either_20_data[either_20_data$response > 0,])
[1] 123
nrow(both_10_data[both_10_data$response > 0,])
[1] 91
nrow(both_20_data[both_20_data$response > 0,])
[1] 128
ggplot(merlin_species_data, aes(x = response, y = foraging_niche, color = percentile)) + geom_boxplot() + theme_bw()

interaction.plot(merlin_species_data$foraging_niche, merlin_species_data$percentile, merlin_species_data$response)

merlin_foraging_niche_anova <- aov(response~foraging_niche + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_foraging_niche_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 4.894 0.1529 1.333 0.118
Residuals 235 26.952 0.1147
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 59.65 2.29e-13 ***
Residuals 267 6.749 0.0253
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_foraging_niche_anova_i <- aov(response~foraging_niche * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_foraging_niche_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 4.894 0.1529 1.333 0.118
Residuals 235 26.952 0.1147
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 68.706 8.81e-15 ***
foraging_niche:percentile 32 1.591 0.0497 2.266 0.000275 ***
Residuals 235 5.157 0.0219
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_foraging_niche_anova <-aov(increase~foraging_niche, data=merlin_diff_data)
summary(merlin_increase_foraging_niche_anova)
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 5.804 0.1814 1.482 0.0533 .
Residuals 235 28.766 0.1224
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_foraging_niche_tukey <- cld(glht(merlin_increase_foraging_niche_anova, linfct=mcp(foraging_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
merlin_increase_foraging_niche_tukey
Aquatic aerial Aquatic dive Aquatic ground Aquatic perch Aquatic plunge Aquatic surface Fugivore aerial
"a" "a" "a" "a" "a" "a" "a"
Fugivore glean Fugivore ground Generalist Granivore arboreal Granivore ground Herbivore aquatic dive Herbivore aquatic ground
"a" "a" "a" "a" "a" "a" "a"
Herbivore aquatic surface Herbivore arboreal Herbivore ground Invertivore aerial Invertivore bark Invertivore glean arboreal Invertivore ground
"a" "a" "a" "a" "a" "a" "a"
Invertivore sally air Invertivore sally ground Invertivore sally surface Nectarivore aerial Nectarivore glean Omnivore Scavenger ground
"a" "a" "a" "a" "a" "a" "a"
Vertivore aerial Vertivore air to surface Vertivore arboreal Vertivore ground Vertivore perch
"a" "a" "a" "a" "a"

ggplot(birdlife_species_data, aes(x = response, y = foraging_niche, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_foraging_niche_anova <- aov(response~foraging_niche + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_foraging_niche_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 5.519 0.1725 1.531 0.0401 *
Residuals 235 26.470 0.1126
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 60.18 1.84e-13 ***
Residuals 267 5.890 0.0221
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_foraging_niche_anova_i <- aov(response~foraging_niche * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_foraging_niche_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 5.519 0.1725 1.531 0.0401 *
Residuals 235 26.470 0.1126
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 67.870 1.22e-14 ***
foraging_niche:percentile 32 1.293 0.0404 2.066 0.00118 **
Residuals 235 4.596 0.0196
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_foraging_niche_anova <-aov(increase~foraging_niche, data=birdlife_diff_data)
summary(birdlife_increase_foraging_niche_anova)
Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche 32 4.85 0.1517 1.09 0.347
Residuals 235 32.71 0.1392
birdlife_increase_foraging_niche_tukey <- cld(glht(birdlife_increase_foraging_niche_anova, linfct=mcp(foraging_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
Completion with error > abseps
birdlife_increase_foraging_niche_tukey
Aquatic aerial Aquatic dive Aquatic ground Aquatic perch Aquatic plunge Aquatic surface Fugivore aerial
"a" "a" "a" "a" "a" "a" "a"
Fugivore glean Fugivore ground Generalist Granivore arboreal Granivore ground Herbivore aquatic dive Herbivore aquatic ground
"a" "a" "a" "a" "a" "a" "a"
Herbivore aquatic surface Herbivore arboreal Herbivore ground Invertivore aerial Invertivore bark Invertivore glean arboreal Invertivore ground
"a" "a" "a" "a" "a" "a" "a"
Invertivore sally air Invertivore sally ground Invertivore sally surface Nectarivore aerial Nectarivore glean Omnivore Scavenger ground
"a" "a" "a" "a" "a" "a" "a"
Vertivore aerial Vertivore air to surface Vertivore arboreal Vertivore ground Vertivore perch
"a" "a" "a" "a" "a"
birdlife_diff_data2 <- with.tukey.label.as.group(birdlife_increase_foraging_niche_tukey, birdlife_diff_data, c("foraging_niche" = "category"))
ggplot(birdlife_diff_data2, aes(x = increase, y = foraging_niche, color = group)) + geom_boxplot() + theme_bw()

library(ggpubr)
pc_axis_figure <- function(dataset) {
annotate_figure(
ggarrange(
ggplot(dataset, aes(x = pc1, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
ggplot(dataset, aes(x = pc2, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
ggplot(dataset, aes(x = pc3, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
ggplot(dataset, aes(x = pc4, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
nrow = 2, ncol = 2, common.legend = T, label.x = 0),
left = text_grob("log(response)", rot = 90))
}
pc_axis_figure(merlin_species_data)
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).


library(lme4)
merlin_pc1_model = lmer(response ~ pc1 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc1_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
pc1 1 0.00042 0.00042 0.0169
percentile 1 1.50774 1.50774 59.9817
pc1:percentile 1 0.06215 0.06215 2.4724
summary(merlin_pc1_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc1 * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: -8.6
Scaled residuals:
Min 1Q Median 3Q Max
-2.4461 -0.5197 0.0155 0.1840 3.3433
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04729 0.2175
Residual 0.02514 0.1585
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 0.117739 0.022322 5.275
pc1 -0.005011 0.006481 -0.773
percentile0.75 0.086293 0.018597 4.640
pc1:percentile0.75 0.008490 0.005399 1.572
Correlation of Fixed Effects:
(Intr) pc1 pr0.75
pc1 -0.676
percntl0.75 -0.417 0.282
pc1:prc0.75 0.282 -0.417 -0.676
merlin_pc2_model = lmer(response ~ pc2 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc2_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
pc2 1 0.01486 0.01486 0.5864
percentile 1 1.50774 1.50774 59.5009
pc2:percentile 1 0.00812 0.00812 0.3203
summary(merlin_pc2_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc2 * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: -11.2
Scaled residuals:
Min 1Q Median 3Q Max
-2.3691 -0.5150 0.0879 0.1354 3.3292
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04706 0.2169
Residual 0.02534 0.1592
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 0.104389 0.016836 6.200
pc2 -0.008532 0.018597 -0.459
percentile0.75 0.104347 0.014086 7.408
pc2:percentile0.75 -0.008805 0.015559 -0.566
Correlation of Fixed Effects:
(Intr) pc2 pr0.75
pc2 0.217
percntl0.75 -0.418 -0.091
pc2:prc0.75 -0.091 -0.418 0.217
merlin_pc3_model = lmer(response ~ pc3 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc3_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
pc3 1 0.00044 0.00044 0.0187
percentile 1 1.50774 1.50774 63.7963
pc3:percentile 1 0.46195 0.46195 19.5464
summary(merlin_pc3_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc3 * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: -30.5
Scaled residuals:
Min 1Q Median 3Q Max
-2.8609 -0.4057 -0.0338 0.2719 3.7473
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04804 0.2192
Residual 0.02363 0.1537
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 0.10758 0.01638 6.568
pc3 -0.04333 0.02594 -1.670
percentile0.75 0.10282 0.01330 7.730
pc3:percentile0.75 0.09314 0.02107 4.421
Correlation of Fixed Effects:
(Intr) pc3 pr0.75
pc3 -0.055
percntl0.75 -0.406 0.022
pc3:prc0.75 0.022 -0.406 -0.055
merlin_pc4_model = lmer(response ~ pc4 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc4_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
pc4 1 0.06576 0.06576 2.6061
percentile 1 1.50774 1.50774 59.7558
pc4:percentile 1 0.03687 0.03687 1.4612
summary(merlin_pc4_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc4 * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: -17
Scaled residuals:
Min 1Q Median 3Q Max
-2.4101 -0.5034 0.0731 0.1400 3.4938
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04666 0.2160
Residual 0.02523 0.1588
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 0.10678 0.01640 6.513
pc4 0.03400 0.03543 0.960
percentile0.75 0.10683 0.01374 7.777
pc4:percentile0.75 0.03588 0.02969 1.209
Correlation of Fixed Effects:
(Intr) pc4 pr0.75
pc4 0.046
percntl0.75 -0.419 -0.019
pc4:prc0.75 -0.019 -0.419 0.046
pc_axis_figure(birdlife_species_data)
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).


ggplot(merlin_species_data, aes(x = response, y = is_nocturnal, color = percentile)) + geom_boxplot() + theme_bw()

merlin_nocturnal_anova <- aov(response~is_nocturnal + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_nocturnal_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal 1 0.462 0.4615 3.912 0.049 *
Residuals 266 31.384 0.1180
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 59.65 2.29e-13 ***
Residuals 267 6.749 0.0253
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_nocturnal_anova_i <- aov(response~is_nocturnal * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_nocturnal_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal 1 0.462 0.4615 3.912 0.049 *
Residuals 266 31.384 0.1180
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.508 1.5077 60.685 1.51e-13 ***
is_nocturnal:percentile 1 0.140 0.1396 5.618 0.0185 *
Residuals 266 6.609 0.0248
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(birdlife_species_data, aes(x = response, y = is_nocturnal, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_nocturnal_anova <- aov(response~is_nocturnal + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_nocturnal_anova)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal 1 0.20 0.1982 1.658 0.199
Residuals 266 31.79 0.1195
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 60.18 1.84e-13 ***
Residuals 267 5.890 0.0221
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_nocturnal_anova_i <- aov(response~is_nocturnal * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_nocturnal_anova_i)
Error: niche_name
Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal 1 0.20 0.1982 1.658 0.199
Residuals 266 31.79 0.1195
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
percentile 1 1.327 1.3274 60.370 1.72e-13 ***
is_nocturnal:percentile 1 0.041 0.0407 1.852 0.175
Residuals 266 5.849 0.0220
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(merlin_species_data, aes(x = total_species, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw()
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).

merlin_species_count_model = lmer(response ~ total_species * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_species_count_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
total_species 1 0.00052 0.00052 0.0206
percentile 1 1.50774 1.50774 59.4316
total_species:percentile 1 0.00026 0.00026 0.0103
summary(merlin_species_count_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ total_species * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: 8.6
Scaled residuals:
Min 1Q Median 3Q Max
-2.3523 -0.5462 0.1109 0.1216 3.2582
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04717 0.2172
Residual 0.02537 0.1593
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 1.064e-01 1.690e-02 6.295
total_species -1.420e-05 1.612e-04 -0.088
percentile0.75 1.064e-01 1.414e-02 7.527
total_species:percentile0.75 -1.367e-05 1.348e-04 -0.101
Correlation of Fixed Effects:
(Intr) ttl_sp pr0.75
total_specs -0.229
percntl0.75 -0.418 0.096
ttl_sp:0.75 0.096 -0.418 -0.229
birdlife_species_count_model = lmer(response ~ total_species * percentile + (1|niche_name), data=birdlife_species_data)
anova(birdlife_species_count_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
total_species 1 0.0000 0.0000 0.0001
percentile 1 1.3274 1.3274 59.9531
total_species:percentile 1 0.0000 0.0000 0.0001
summary(birdlife_species_count_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ total_species * percentile + (1 | niche_name)
Data: birdlife_species_data
REML criterion at convergence: -26.3
Scaled residuals:
Min 1Q Median 3Q Max
-2.5919 -0.5189 0.0633 0.1497 3.4600
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.04906 0.2215
Residual 0.02214 0.1488
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 9.946e-02 1.675e-02 5.939
total_species 9.392e-07 1.597e-04 0.006
percentile0.75 9.949e-02 1.321e-02 7.534
total_species:percentile0.75 1.518e-06 1.260e-04 0.012
Correlation of Fixed Effects:
(Intr) ttl_sp pr0.75
total_specs -0.229
percntl0.75 -0.394 0.090
ttl_sp:0.75 0.090 -0.394 -0.229
merlin_species_data$present <- merlin_species_data$response > 0
ggplot(merlin_species_data, aes(x = log(total_species), y = present, color = percentile)) + geom_boxplot() + theme_bw()

merlin_present_model = lmer(present ~ log(total_species) * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_present_model)
Analysis of Variance Table
npar Sum Sq Mean Sq F value
log(total_species) 1 7.6804 7.6804 145.5124
percentile 1 1.9104 1.9104 36.1952
log(total_species):percentile 1 0.0496 0.0496 0.9393
summary(merlin_present_model)
Linear mixed model fit by REML ['lmerMod']
Formula: present ~ log(total_species) * percentile + (1 | niche_name)
Data: merlin_species_data
REML criterion at convergence: 410.7
Scaled residuals:
Min 1Q Median 3Q Max
-2.25242 -0.44048 0.02734 0.24296 2.14911
Random effects:
Groups Name Variance Std.Dev.
niche_name (Intercept) 0.11259 0.3356
Residual 0.05278 0.2297
Number of obs: 536, groups: niche_name, 268
Fixed effects:
Estimate Std. Error t value
(Intercept) 0.10521 0.03325 3.164
log(total_species) 0.19281 0.01685 11.446
percentile0.75 0.13652 0.02657 5.139
log(total_species):percentile0.75 -0.01304 0.01346 -0.969
Correlation of Fixed Effects:
(Intr) lg(t_) pr0.75
lg(ttl_spc) -0.665
percntl0.75 -0.399 0.266
lg(t_):0.75 0.266 -0.399 -0.665
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShiaWdycXVlcnkpCmxpYnJhcnkoTXVNSW4pCmBgYAoKYGBge3J9CnJlc3BvbnNlIDwtIHRyeShzeXN0ZW0oJ34vZ29vZ2xlLWNsb3VkLXNkay9iaW4vZ2Nsb3VkIHByb2plY3RzIGxpc3QgLS1xdWlldCcsIGludGVybiA9IFQpKQpwcm9qZWN0aWQgPC0gc3Ryc3BsaXQocmVzcG9uc2VbMl0sICIgIilbWzFdXVsxXQpgYGAKCmBgYHtyfQpvcHRpb25zKG5hLmFjdGlvbiA9ICJuYS5mYWlsIikgCmBgYAoKYGBge3J9CnNvdXJjZSgiLi9kcmVkZ2VfZnVuY3Rpb25zLlIiKQpgYGAKCmBgYHtyfQpkcmVkZ2VfYW5kX3N1YnNldCA8LSBmdW5jdGlvbihkYXRhKSB7CiAgbW9kZWwgPC0gbG0oCiAgICByZXNwb25zZSB+IGZvcmFnaW5nX25pY2hlICsgdHJvcGhpY19uaWNoZSArIGlzX25vY3R1cm5hbCArIHBjMSArIHBjMiArIHBjMyArIHBjNCArIHRvdGFsX3NwZWNpZXMsCiAgICBkYXRhPWRhdGEKICApCiAgZHJlZGdlX3Jlc3VsdCA8LSBkcmVkZ2UobW9kZWwpCiAgc3VtbWFyeShtb2RlbC5hdmcoZHJlZGdlX3Jlc3VsdCwgc3Vic2V0ID0gZGVsdGEgPCAxMCkpCn0KYGBgCgpgYGB7cn0KbG9hZF9uaWNoZV9kYXRhIDwtIGZ1bmN0aW9uKCkgewogIGZpbGVuYW1lIDwtICdzcGVjaWVzX2FuYWx5c2lzX2NhY2hlLmNzdicKICAKICBpZiAoIWZpbGUuZXhpc3RzKGZpbGVuYW1lKSkgewogICAgCiAgICBzcWwgPC0gIgogICAgICAgIFNFTEVDVCAKICAgICAgICAgIG5pY2hlX25hbWUsCiAgICAgICAgICBmb3JhZ2luZ19uaWNoZSwgCiAgICAgICAgICB0cm9waGljX25pY2hlLCAKICAgICAgICAgIGlzX25vY3R1cmFsLCAKICAgICAgICAgIHRvdGFsX3NwZWNpZXMsCiAgICAgICAgICBtZXJsaW5fMTBfcGVyY19yYXRpbywgCiAgICAgICAgICBtZXJsaW5fMjBfcGVyY19yYXRpbywgCiAgICAgICAgICBiaXJkbGlmZV8xMF9wZXJjX3JhdGlvLCAKICAgICAgICAgIGJpcmRsaWZlXzIwX3BlcmNfcmF0aW8sIAogICAgICAgICAgZWl0aGVyXzEwX3BlcmNfcmF0aW8sIAogICAgICAgICAgZWl0aGVyXzIwX3BlcmNfcmF0aW8sIAogICAgICAgICAgYm90aF8xMF9wZXJjX3JhdGlvLCAKICAgICAgICAgIGJvdGhfMjBfcGVyY19yYXRpbywgCiAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGMxLm1lYW4gQVMgcGMxLCAKICAgICAgICAgIGJvZHlfbW9ycGhzcGFjZS5wYzIubWVhbiBBUyBwYzIsIAogICAgICAgICAgYm9keV9tb3JwaHNwYWNlLnBjMy5tZWFuIEFTIHBjMywgCiAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGM0Lm1lYW4gQVMgcGM0CiAgICAgICAgRlJPTSBgZW5kbGVzcy1tYXR0ZXItMjk3MjE0Lm1vZGVsMi5uaWNoZV9hbmFseXNpc19tb2RlbGAgTElNSVQgMTAwMCAKICAgICIKICAKICAgIHRiIDwtIGJxX3Byb2plY3RfcXVlcnkocHJvamVjdGlkLCBzcWwpCgogICAgZGF0YSA8LSBicV90YWJsZV9kb3dubG9hZCh0YikKICAgIHdyaXRlX2NzdihkYXRhLCBmaWxlbmFtZSkKICB9CiAgCiAgZGF0YSA8LSByZWFkX2NzdihmaWxlbmFtZSkKICAKICBkYXRhW2lzLm5hKGRhdGEkZm9yYWdpbmdfbmljaGUpLF0kZm9yYWdpbmdfbmljaGUgPC0gJ09tbml2b3JlJwogIAogIGRhdGEkZm9yYWdpbmdfbmljaGUgPSBhcy5mYWN0b3IoZGF0YSRmb3JhZ2luZ19uaWNoZSkKICBkYXRhJHRyb3BoaWNfbmljaGUgPSBhcy5mYWN0b3IoZGF0YSR0cm9waGljX25pY2hlKQogIGRhdGEkaXNfbm9jdHVybmFsID0gYXMuZmFjdG9yKGRhdGEkaXNfbm9jdHVyYWwpCiAgCiAgZGF0YQp9CgpkYXRhX2Zvcl9yZXNwb25zZSA8LSBmdW5jdGlvbihjb2x1bW5fbmFtZV9mb3JfcmVzcG9uc2UpIHsKICBkYXRhIDwtIGxvYWRfbmljaGVfZGF0YSgpCiAgbmFtZXMoZGF0YSlbbmFtZXMoZGF0YSkgPT0gY29sdW1uX25hbWVfZm9yX3Jlc3BvbnNlXSA8LSAicmVzcG9uc2UiCiAgCiAgZGF0YVssYygibmljaGVfbmFtZSIsICJyZXNwb25zZSIsICJmb3JhZ2luZ19uaWNoZSIsICJ0cm9waGljX25pY2hlIiwgImlzX25vY3R1cm5hbCIsICJwYzEiLCAicGMyIiwgInBjMyIsICJwYzQiLCAidG90YWxfc3BlY2llcyIpXQp9CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjAuMjUgUGVyY2VudGlsZSAtIDEwJSBvZiBzcGVjaWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3J9Cm1lcmxpbl8xMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdtZXJsaW5fMTBfcGVyY19yYXRpbycpCm1lcmxpbl8xMF9kYXRhCmBgYAoKCmBgYHtyfQptZXJsaW5fMTBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KG1lcmxpbl8xMF9kYXRhKQptZXJsaW5fMTBfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdtZXJsaW5fMTAnLCAnc3BlY2llcycsIG1lcmxpbl8xMF9yZXN1bHQpCm1lcmxpbl8xMF9zdW1tCmBgYAoKYGBge3J9CmJpcmRsaWZlXzEwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JpcmRsaWZlXzEwX3BlcmNfcmF0aW8nKQpiaXJkbGlmZV8xMF9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQoYmlyZGxpZmVfMTBfZGF0YSkKYmlyZGxpZmVfMTBfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdiaXJkbGlmZV8xMCcsICdzcGVjaWVzJywgYmlyZGxpZmVfMTBfcmVzdWx0KQpiaXJkbGlmZV8xMF9zdW1tCmBgYAoKCmBgYHtyfQpib3RoXzEwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JvdGhfMTBfcGVyY19yYXRpbycpCmJvdGhfMTBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJvdGhfMTBfZGF0YSkKYm90aF8xMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2JvdGhfMTAnLCAnc3BlY2llcycsIGJvdGhfMTBfcmVzdWx0KQpib3RoXzEwX3N1bW0KYGBgCgoKYGBge3J9CmVpdGhlcl8xMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdlaXRoZXJfMTBfcGVyY19yYXRpbycpCmVpdGhlcl8xMF9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQoZWl0aGVyXzEwX2RhdGEpCmVpdGhlcl8xMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2VpdGhlcl8xMCcsICdzcGVjaWVzJywgZWl0aGVyXzEwX3Jlc3VsdCkKZWl0aGVyXzEwX3N1bW0KYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRnVsbCByZXN1bHQgZm9yIDEwJSBvZiBzcGVjaWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KYWxsX3NwZWNpZXNfcmVzdWx0cyA8LSBmdWxsX2pvaW4oZnVsbF9qb2luKG1lcmxpbl8xMF9zdW1tLCBiaXJkbGlmZV8xMF9zdW1tKSwgZnVsbF9qb2luKGJvdGhfMTBfc3VtbSwgZWl0aGVyXzEwX3N1bW0pKQp3cml0ZV9jc3YoYWxsX3NwZWNpZXNfcmVzdWx0cywgInNwZWNpZXNfYW5hbHlzaXNfcmVzdWx0XzEwX3BlcmMuY3N2IikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KMC43NSBQZXJjZW50aWxlIC0gMjAlIG9mIHNwZWNpZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KbWVybGluXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ21lcmxpbl8yMF9wZXJjX3JhdGlvJykKbWVybGluXzIwX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChtZXJsaW5fMjBfZGF0YSkKbWVybGluXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnbWVybGluXzIwJywgJ3NwZWNpZXMnLCBtZXJsaW5fMjBfcmVzdWx0KQptZXJsaW5fMjBfc3VtbQpgYGAKCmBgYHtyfQpiaXJkbGlmZV8yMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdiaXJkbGlmZV8yMF9wZXJjX3JhdGlvJykKYmlyZGxpZmVfMjBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJpcmRsaWZlXzIwX2RhdGEpCmJpcmRsaWZlXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnYmlyZGxpZmVfMjAnLCAnc3BlY2llcycsIGJpcmRsaWZlXzIwX3Jlc3VsdCkKYmlyZGxpZmVfMjBfc3VtbQpgYGAKCmBgYHtyfQpib3RoXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JvdGhfMjBfcGVyY19yYXRpbycpCmJvdGhfMjBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJvdGhfMjBfZGF0YSkKYm90aF8yMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2JvdGhfMjAnLCAnc3BlY2llcycsIGJvdGhfMjBfcmVzdWx0KQpib3RoXzIwX3N1bW0KYGBgCgpgYGB7cn0KZWl0aGVyXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2VpdGhlcl8yMF9wZXJjX3JhdGlvJykKZWl0aGVyXzIwX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChlaXRoZXJfMjBfZGF0YSkKZWl0aGVyXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnZWl0aGVyXzIwJywgJ3NwZWNpZXMnLCBlaXRoZXJfMjBfcmVzdWx0KQplaXRoZXJfMjBfc3VtbQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGdWxsIHJlc3VsdCBmb3IgMTAlIG9mIHNwZWNpZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQphbGxfc3BlY2llc19yZXN1bHRzIDwtIGZ1bGxfam9pbihmdWxsX2pvaW4obWVybGluXzIwX3N1bW0sIGJpcmRsaWZlXzIwX3N1bW0pLCBmdWxsX2pvaW4oYm90aF8yMF9zdW1tLCBlaXRoZXJfMjBfc3VtbSkpCndyaXRlX2NzdihhbGxfc3BlY2llc19yZXN1bHRzLCAic3BlY2llc19hbmFseXNpc19yZXN1bHRfMjBfcGVyYy5jc3YiKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpDb21wYXJpbmcgdGhlIDIgcGVyY2VudGlsZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KZ2dwbG90KG1lcmxpbl8xMF9kYXRhLCBhZXMoeCA9IHJlc3BvbnNlKSkgKyBnZW9tX2Jhcih3aWR0aCA9IDAuMSkKYGBgCgpgYGB7cn0KYmluZF9zZXRzIDwtIGZ1bmN0aW9uKGZpcnN0X3BlcmNlbnRpbGUsIHNlY29uZF9wZXJjZW50aWxlKSB7CiAgZmlyc3RfcGVyY2VudGlsZSRwZXJjZW50aWxlIDwtICIwLjI1IgogIHNlY29uZF9wZXJjZW50aWxlJHBlcmNlbnRpbGUgPC0gIjAuNzUiCiAgcmJpbmQoZmlyc3RfcGVyY2VudGlsZSwgc2Vjb25kX3BlcmNlbnRpbGUpCn0KCm1lcmxpbl9zcGVjaWVzX2RhdGEgPC0gYmluZF9zZXRzKG1lcmxpbl8xMF9kYXRhLCAgbWVybGluXzIwX2RhdGEpCmJpcmRsaWZlX3NwZWNpZXNfZGF0YSA8LSBiaW5kX3NldHMoYmlyZGxpZmVfMTBfZGF0YSwgIGJpcmRsaWZlXzIwX2RhdGEpCmVpdGhlcl9zcGVjaWVzX2RhdGEgPC0gYmluZF9zZXRzKGVpdGhlcl8xMF9kYXRhLCAgZWl0aGVyXzIwX2RhdGEpCmJvdGhfc3BlY2llc19kYXRhIDwtIGJpbmRfc2V0cyhib3RoXzEwX2RhdGEsICBib3RoXzIwX2RhdGEpCmBgYAoKYGBge3J9CmRpZmZfc2V0IDwtIGZ1bmN0aW9uKGZpcnN0X3BlcmNlbnRpbGUsIHNlY29uZF9wZXJjZW50aWxlKSB7CiAgc2Vjb25kX3BlcmNlbnRpbGUkcmVzcG9uc2VfMjAgPC0gc2Vjb25kX3BlcmNlbnRpbGUkcmVzcG9uc2UKICAKICByZXN1bHQgPC0gcmlnaHRfam9pbihmaXJzdF9wZXJjZW50aWxlLCBzZWNvbmRfcGVyY2VudGlsZVssYygibmljaGVfbmFtZSIsICJyZXNwb25zZV8yMCIpXSwgYnkgPSBjKCJuaWNoZV9uYW1lIikpCiAgcmVzdWx0JGRpZmYgPC0gcmVzdWx0JHJlc3BvbnNlXzIwIC0gcmVzdWx0JHJlc3BvbnNlCiAgcmVzdWx0JGluY3JlYXNlIDwtIHJlc3VsdCRkaWZmIC8gcmVzdWx0JHJlc3BvbnNlXzIwCiAgcmVzdWx0JGluY3JlYXNlW2lzLm5hKHJlc3VsdCRpbmNyZWFzZSldID0gMAogIHJlc3VsdCRyZXNwb25zZV8xMCA8LSByZXN1bHQkcmVzcG9uc2UKICByZXN1bHRbLGMoInJlc3BvbnNlXzEwIiwgInJlc3BvbnNlXzIwIiwgImRpZmYiLCAiaW5jcmVhc2UiLCAiZm9yYWdpbmdfbmljaGUiLCAidHJvcGhpY19uaWNoZSIsICJpc19ub2N0dXJuYWwiLCAicGMxIiwgInBjMiIsICJwYzMiLCAicGM0IiwgInRvdGFsX3NwZWNpZXMiKV0KfQoKbWVybGluX2RpZmZfZGF0YSA8LSBkaWZmX3NldChtZXJsaW5fMTBfZGF0YSwgIG1lcmxpbl8yMF9kYXRhKQpiaXJkbGlmZV9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoYmlyZGxpZmVfMTBfZGF0YSwgIGJpcmRsaWZlXzIwX2RhdGEpCmVpdGhlcl9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoZWl0aGVyXzEwX2RhdGEsICBlaXRoZXJfMjBfZGF0YSkKYm90aF9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoYm90aF8xMF9kYXRhLCAgYm90aF8yMF9kYXRhKQoKbWVybGluX2RpZmZfZGF0YQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm1lcmxpbl90cm9waGljX25pY2hlX25pY2hlX2Fub3ZhIDwtIGFvdihyZXNwb25zZX50cm9waGljX25pY2hlICsgcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEpCgptZXJsaW5fdHJvcGhpY19uaWNoZV9uaWNoZV9hbm92YV9pIDwtIGFvdihyZXNwb25zZX50cm9waGljX25pY2hlICogcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmFfaSkKYGBgCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3QobWVybGluX2RpZmZfZGF0YSRpbmNyZWFzZSwgbWVybGluX2RpZmZfZGF0YSR0cm9waGljX25pY2hlKQpgYGAKYGBge3J9CmxpYnJhcnkobXVsdGNvbXApCm1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEgPC1hb3YoaW5jcmVhc2V+dHJvcGhpY19uaWNoZSwgZGF0YT1tZXJsaW5fZGlmZl9kYXRhKQpzdW1tYXJ5KG1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEpCgptZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5IDwtIGNsZChnbGh0KG1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AodHJvcGhpY19uaWNoZT0iVHVrZXkiKSkpCgptZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9CnBsb3QobWVybGluX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSkKYGBgCmBgYHtyfQp3aXRoLnR1a2V5LmxhYmVsLmFzLmdyb3VwIDwtIGZ1bmN0aW9uKHR1a2V5LCBkYXRhc2V0LCBqb2luX2J5KSB7CiAgbGFiZWxzIDwtIGRhdGEuZnJhbWUodHVrZXkkbWNsZXR0ZXJzJExldHRlcnMpCiAgbGFiZWxzJGNhdGVnb3J5IDwtIHJvd25hbWVzKGxhYmVscykKICBjb2xuYW1lcyhsYWJlbHMpIDwtIGMoImdyb3VwIiwgImNhdGVnb3J5IikKICAKICAKICBsZWZ0X2pvaW4oZGF0YXNldCwgbGFiZWxzLCBieSA9IGpvaW5fYnkpCn0KYGBgCgpgYGB7cn0KbWVybGluX2RpZmZfZGF0YTEgPC0gd2l0aC50dWtleS5sYWJlbC5hcy5ncm91cChtZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5LCBtZXJsaW5fZGlmZl9kYXRhLCBjKCJ0cm9waGljX25pY2hlIiA9ICJjYXRlZ29yeSIpKQptZXJsaW5fZGlmZl9kYXRhMQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX2RpZmZfZGF0YTEsIGFlcyh4ID0gaW5jcmVhc2UsIHkgPSB0cm9waGljX25pY2hlLCBjb2xvciA9IGdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEgPC0gYW92KHJlc3BvbnNlfnRyb3BoaWNfbmljaGUgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEpCgpiaXJkbGlmZV90cm9waGljX25pY2hlX25pY2hlX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfnRyb3BoaWNfbmljaGUgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmFfaSkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfaW5jcmVhc2VfdHJvcGljX25pY2hlX2Fub3ZhIDwtYW92KGluY3JlYXNlfnRyb3BoaWNfbmljaGUsIGRhdGE9YmlyZGxpZmVfZGlmZl9kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV9hbm92YSkKCmJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSA8LSBjbGQoZ2xodChiaXJkbGlmZV9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AodHJvcGhpY19uaWNoZT0iVHVrZXkiKSkpCgpiaXJkbGlmZV9pbmNyZWFzZV90cm9waWNfbmljaGVfdHVrZXkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfZGlmZl9kYXRhMSA8LSB3aXRoLnR1a2V5LmxhYmVsLmFzLmdyb3VwKGJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSwgYmlyZGxpZmVfZGlmZl9kYXRhLCBjKCJ0cm9waGljX25pY2hlIiA9ICJjYXRlZ29yeSIpKQpnZ3Bsb3QoYmlyZGxpZmVfZGlmZl9kYXRhMSwgYWVzKHggPSBpbmNyZWFzZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gZ3JvdXApKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZWl0aGVyX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmdncGxvdChib3RoX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm5yb3cobWVybGluXzEwX2RhdGFbbWVybGluXzEwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCm5yb3cobWVybGluXzIwX2RhdGFbbWVybGluXzIwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCmBgYAoKYGBge3J9Cm5yb3coYmlyZGxpZmVfMTBfZGF0YVtiaXJkbGlmZV8xMF9kYXRhJHJlc3BvbnNlID4gMCxdKQpucm93KGJpcmRsaWZlXzIwX2RhdGFbYmlyZGxpZmVfMjBfZGF0YSRyZXNwb25zZSA+IDAsXSkKYGBgCgpgYGB7cn0KbnJvdyhlaXRoZXJfMTBfZGF0YVtlaXRoZXJfMTBfZGF0YSRyZXNwb25zZSA+IDAsXSkKbnJvdyhlaXRoZXJfMjBfZGF0YVtlaXRoZXJfMjBfZGF0YSRyZXNwb25zZSA+IDAsXSkKYGBgCgpgYGB7cn0KbnJvdyhib3RoXzEwX2RhdGFbYm90aF8xMF9kYXRhJHJlc3BvbnNlID4gMCxdKQpucm93KGJvdGhfMjBfZGF0YVtib3RoXzIwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCmBgYAoKYGBge3J9CmdncGxvdChtZXJsaW5fc3BlY2llc19kYXRhLCBhZXMoeCA9IHJlc3BvbnNlLCB5ID0gZm9yYWdpbmdfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmludGVyYWN0aW9uLnBsb3QobWVybGluX3NwZWNpZXNfZGF0YSRmb3JhZ2luZ19uaWNoZSwgbWVybGluX3NwZWNpZXNfZGF0YSRwZXJjZW50aWxlLCBtZXJsaW5fc3BlY2llc19kYXRhJHJlc3BvbnNlKQpgYGAKCmBgYHtyfQptZXJsaW5fZm9yYWdpbmdfbmljaGVfYW5vdmEgPC0gYW92KHJlc3BvbnNlfmZvcmFnaW5nX25pY2hlICsgcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhKQoKbWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfmZvcmFnaW5nX25pY2hlICogcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kpCmBgYAoKYGBge3J9Cm1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSA8LWFvdihpbmNyZWFzZX5mb3JhZ2luZ19uaWNoZSwgZGF0YT1tZXJsaW5fZGlmZl9kYXRhKQpzdW1tYXJ5KG1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSkKCm1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV90dWtleSA8LSBjbGQoZ2xodChtZXJsaW5faW5jcmVhc2VfZm9yYWdpbmdfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AoZm9yYWdpbmdfbmljaGU9IlR1a2V5IikpKQoKbWVybGluX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9Cm1lcmxpbl9kaWZmX2RhdGEyIDwtIHdpdGgudHVrZXkubGFiZWwuYXMuZ3JvdXAobWVybGluX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5LCBtZXJsaW5fZGlmZl9kYXRhLCBjKCJmb3JhZ2luZ19uaWNoZSIgPSAiY2F0ZWdvcnkiKSkKZ2dwbG90KG1lcmxpbl9kaWZmX2RhdGEyLCBhZXMoeCA9IGluY3JlYXNlLCB5ID0gZm9yYWdpbmdfbmljaGUsIGNvbG9yID0gZ3JvdXApKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IGZvcmFnaW5nX25pY2hlLCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQpiaXJkbGlmZV9mb3JhZ2luZ19uaWNoZV9hbm92YSA8LSBhb3YocmVzcG9uc2V+Zm9yYWdpbmdfbmljaGUgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhKQoKYmlyZGxpZmVfZm9yYWdpbmdfbmljaGVfYW5vdmFfaSA8LSBhb3YocmVzcG9uc2V+Zm9yYWdpbmdfbmljaGUgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kpCmBgYAoKYGBge3J9CmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhIDwtYW92KGluY3JlYXNlfmZvcmFnaW5nX25pY2hlLCBkYXRhPWJpcmRsaWZlX2RpZmZfZGF0YSkKc3VtbWFyeShiaXJkbGlmZV9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSkKCmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5IDwtIGNsZChnbGh0KGJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhLCBsaW5mY3Q9bWNwKGZvcmFnaW5nX25pY2hlPSJUdWtleSIpKSkKCmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9CmJpcmRsaWZlX2RpZmZfZGF0YTIgPC0gd2l0aC50dWtleS5sYWJlbC5hcy5ncm91cChiaXJkbGlmZV9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV90dWtleSwgYmlyZGxpZmVfZGlmZl9kYXRhLCBjKCJmb3JhZ2luZ19uaWNoZSIgPSAiY2F0ZWdvcnkiKSkKZ2dwbG90KGJpcmRsaWZlX2RpZmZfZGF0YTIsIGFlcyh4ID0gaW5jcmVhc2UsIHkgPSBmb3JhZ2luZ19uaWNoZSwgY29sb3IgPSBncm91cCkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dwdWJyKQpgYGAKCmBgYHtyfQpwY19heGlzX2ZpZ3VyZSA8LSBmdW5jdGlvbihkYXRhc2V0KSB7CiAgYW5ub3RhdGVfZmlndXJlKApnZ2FycmFuZ2UoCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyh4ID0gcGMxLCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSArIHJyZW1vdmUoInlsYWIiKSwKICBnZ3Bsb3QoZGF0YXNldCwgYWVzKHggPSBwYzIsIHkgPSBsb2cocmVzcG9uc2UpLCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKyB0aGVtZV9idygpICsgcnJlbW92ZSgieWxhYiIpLAogIGdncGxvdChkYXRhc2V0LCBhZXMoeCA9IHBjMywgeSA9IGxvZyhyZXNwb25zZSksIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkgKyBycmVtb3ZlKCJ5bGFiIiksCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyh4ID0gcGM0LCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSArIHJyZW1vdmUoInlsYWIiKSwKICBucm93ID0gMiwgbmNvbCA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbC54ID0gMCksCmxlZnQgPSB0ZXh0X2dyb2IoImxvZyhyZXNwb25zZSkiLCByb3QgPSA5MCkpCn0KYGBgCgpgYGB7cn0KcGNfYXhpc19maWd1cmUobWVybGluX3NwZWNpZXNfZGF0YSkKYGBgCgpgYGB7cn0KbGlicmFyeShsbWU0KQptZXJsaW5fcGMxX21vZGVsID0gbG1lcihyZXNwb25zZSB+IHBjMSAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcGMxX21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9wYzFfbW9kZWwpCmBgYAoKYGBge3J9Cm1lcmxpbl9wYzJfbW9kZWwgPSBsbWVyKHJlc3BvbnNlIH4gcGMyICogcGVyY2VudGlsZSArICgxfG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCmFub3ZhKG1lcmxpbl9wYzJfbW9kZWwpCnN1bW1hcnkobWVybGluX3BjMl9tb2RlbCkKYGBgCgpgYGB7cn0KbWVybGluX3BjM19tb2RlbCA9IGxtZXIocmVzcG9uc2UgfiBwYzMgKiBwZXJjZW50aWxlICsgKDF8bmljaGVfbmFtZSksIGRhdGE9bWVybGluX3NwZWNpZXNfZGF0YSkKYW5vdmEobWVybGluX3BjM19tb2RlbCkKc3VtbWFyeShtZXJsaW5fcGMzX21vZGVsKQpgYGAKCmBgYHtyfQptZXJsaW5fcGM0X21vZGVsID0gbG1lcihyZXNwb25zZSB+IHBjNCAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcGM0X21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9wYzRfbW9kZWwpCmBgYAoKYGBge3J9CnBjX2F4aXNfZmlndXJlKGJpcmRsaWZlX3NwZWNpZXNfZGF0YSkKYGBgCgpgYGB7cn0KZ2dwbG90KG1lcmxpbl9zcGVjaWVzX2RhdGEsIGFlcyh4ID0gcmVzcG9uc2UsIHkgPSBpc19ub2N0dXJuYWwsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm1lcmxpbl9ub2N0dXJuYWxfYW5vdmEgPC0gYW92KHJlc3BvbnNlfmlzX25vY3R1cm5hbCArIHBlcmNlbnRpbGUgKyBFcnJvcihuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQpzdW1tYXJ5KG1lcmxpbl9ub2N0dXJuYWxfYW5vdmEpCgptZXJsaW5fbm9jdHVybmFsX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfmlzX25vY3R1cm5hbCAqIHBlcmNlbnRpbGUgKyBFcnJvcihuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQpzdW1tYXJ5KG1lcmxpbl9ub2N0dXJuYWxfYW5vdmFfaSkKYGBgCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IGlzX25vY3R1cm5hbCwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX2JveHBsb3QoKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfbm9jdHVybmFsX2Fub3ZhIDwtIGFvdihyZXNwb25zZX5pc19ub2N0dXJuYWwgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX25vY3R1cm5hbF9hbm92YSkKCmJpcmRsaWZlX25vY3R1cm5hbF9hbm92YV9pIDwtIGFvdihyZXNwb25zZX5pc19ub2N0dXJuYWwgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX25vY3R1cm5hbF9hbm92YV9pKQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSB0b3RhbF9zcGVjaWVzLCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQptZXJsaW5fc3BlY2llc19jb3VudF9tb2RlbCA9IGxtZXIocmVzcG9uc2UgfiB0b3RhbF9zcGVjaWVzICogcGVyY2VudGlsZSArICgxfG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCmFub3ZhKG1lcmxpbl9zcGVjaWVzX2NvdW50X21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9zcGVjaWVzX2NvdW50X21vZGVsKQpgYGAKCmBgYHtyfQpiaXJkbGlmZV9zcGVjaWVzX2NvdW50X21vZGVsID0gbG1lcihyZXNwb25zZSB+IHRvdGFsX3NwZWNpZXMgKiBwZXJjZW50aWxlICsgKDF8bmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQphbm92YShiaXJkbGlmZV9zcGVjaWVzX2NvdW50X21vZGVsKQpzdW1tYXJ5KGJpcmRsaWZlX3NwZWNpZXNfY291bnRfbW9kZWwpCmBgYAoKYGBge3J9Cm1lcmxpbl9zcGVjaWVzX2RhdGEkcHJlc2VudCA8LSBtZXJsaW5fc3BlY2llc19kYXRhJHJlc3BvbnNlID4gMApgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSBsb2codG90YWxfc3BlY2llcyksIHkgPSBwcmVzZW50LCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQptZXJsaW5fcHJlc2VudF9tb2RlbCA9IGxtZXIocHJlc2VudCB+IGxvZyh0b3RhbF9zcGVjaWVzKSAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcHJlc2VudF9tb2RlbCkKc3VtbWFyeShtZXJsaW5fcHJlc2VudF9tb2RlbCkKYGBgCgoKCgo=